﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Money.Interface
{
    // TODO add filter option for edited fields. should this form create a transaction match search type and make things easier?

    public partial class SearchTransactions : Form
    {
        private IDataSet _dataAccessInterface;
        private static SearchTransactions _form = null;

        public TransactionFilter FilterHandler { get; set; }

        public SearchTransactions(IDataSet dataAccessInterface, TransactionMatchRule currentFilter = null)
        {
            InitializeComponent();
            
            _dataAccessInterface = dataAccessInterface;

            ResetDateFields();

            _category.DataSource = _dataAccessInterface.Categories;
            _category.DisplayMember = "Name";
            _category.ValueMember = "Id";

            _categoryGroup.DataSource = _dataAccessInterface.Categories.GetCategoryGroups().ToList();
            _categoryGroup.DisplayMember = "Name";
            _categoryGroup.ValueMember = "Id";

            _account.DataSource = _dataAccessInterface.Accounts;
            _account.DisplayMember = "Name";
            _account.ValueMember = "Name";

            _type.DataSource = Enum.GetValues(typeof(Transaction.TransactionType));

            if (currentFilter != null)
            {
                ApplyCurrentFilter(currentFilter);
            }
         }

        private void ApplyCurrentFilter(TransactionMatchRule currentFilter)
        {
            bool enableInstantUpdate = false;

            if (currentFilter.Account != null && !currentFilter.Account.Equals("[All]", StringComparison.CurrentCultureIgnoreCase) )
            {
                _account.Text = currentFilter.Account;
                _enableAccount.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.StartDate.Year > 2000)
            {
                _startDate.Value = currentFilter.StartDate;
                _enableDate.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.EndDate.Year > 2000)
            {
                _endDate.Value = currentFilter.EndDate;
                _enableDate.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.CategoryGroupId != null)
            {
                _categoryGroup.SelectedValue = currentFilter.CategoryGroupId;
                _enableCategoryGroup.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.CategoryId != null)
            {
                _category.SelectedValue = currentFilter.CategoryId;
                _enableCategory.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.Type != null)
            {
                _type.Text = currentFilter.Type.ToString();
                _enableType.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.Description != null)
            {
                _description.Text = currentFilter.Description;
                _enableDescription.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.MinimumAmount != null)
            {
                _minAmount.Text = currentFilter.MinimumAmount.ToString();
                _enableAmount.Checked = true;
                enableInstantUpdate = true;
            }

            if (currentFilter.MaximumAmount != null)
            {
                _maxAmount.Text = currentFilter.MaximumAmount.ToString();
                _enableAmount.Checked = true;
                enableInstantUpdate = true;
            }

            if (enableInstantUpdate)
            {
                _instantUpdate.Checked = true;
            }
        }

        private void SearchItemChanged_Click(object sender, EventArgs e)
        {
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void ApplyFilter()
        {
            TransactionMatchRule rule = new TransactionMatchRule();

            if (_enableAccount.Checked)
            {
                rule.Account = _account.Text;
            }

            if (_igonoreSign.Checked)
            {
                rule.IgnoreSign = true;
            }
            else
            {
                rule.IgnoreSign = false;
            }

            if (_enableType.Checked)
            {
                try
                {
                    Transaction.TransactionType type = (Transaction.TransactionType)Enum.Parse(typeof(Transaction.TransactionType), _type.Text);
                    rule.Type = type;
                }
                catch
                {
                }
            }

            if (_enableAmount.Checked)
            {
                if (!string.IsNullOrWhiteSpace(_minAmount.Text))
                {
                    try
                    {
                        rule.MinimumAmount = Convert.ToDecimal(_minAmount.Text);
                        _minAmount.BackColor = Color.White;
                    }
                    catch
                    {
                        // conversion error
                        _minAmount.BackColor = Color.Red;
                    }
                }
                if (!string.IsNullOrWhiteSpace(_maxAmount.Text))
                {
                    try
                    {
                        rule.MaximumAmount = Convert.ToDecimal(_maxAmount.Text);
                        _maxAmount.BackColor = Color.White;
                    }
                    catch
                    {
                        // conversion error
                        _maxAmount.BackColor = Color.Red;
                    }
                }
            }

            if (_enableCategory.Checked)
            {
                try
                {
                    rule.CategoryId = (int)_category.SelectedValue;
                }
                catch
                {
                }
            }

            if (_enableCategoryGroup.Checked)
            {
                try
                {
                    rule.CategoryGroupId = (int)_categoryGroup.SelectedValue;
                }
                catch
                {
                }
            }

            if (_enableDate.Checked)
            {
                rule.StartDate = _startDate.Value;
                rule.EndDate = _endDate.Value;
            }

            if (_enableDescription.Checked)
            {
                rule.Description = _description.Text;
            }

            if (FilterHandler != null)
            {
                FilterHandler(rule);
            }
        }

        private void _enableAmount_CheckedChanged(object sender, EventArgs e)
        {
            _maxAmount.Enabled = _minAmount.Enabled = _amountLabel.Enabled = _igonoreSign.Enabled = _enableAmount.Checked;
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void _clearButton_Click(object sender, EventArgs e)
        {
            ClearAllFields();
        }

        private void ClearAllFields()
        {
            _maxAmount.Text = String.Empty;
            _minAmount.Text = String.Empty;
            _description.Text = String.Empty;
            _category.SelectedIndex = -1;
            _categoryGroup.SelectedIndex = -1;
            _account.SelectedIndex = -1;
            _type.SelectedIndex = -1;
            _igonoreSign.Checked = false;

            _maxAmount.BackColor = SystemColors.Window;
            _minAmount.BackColor = SystemColors.Window;

            ResetDateFields();

            _enableType.Checked = _enableDescription.Checked = _enableDate.Checked = _enableCategoryGroup.Checked = _enableCategory.Checked = _enableAmount.Checked = _enableAccount.Checked = false;

            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void ResetDateFields()
        {
            _startDate.Value = (from transaction in _dataAccessInterface.Transactions select transaction.Date).Min();
            _endDate.Value = (from transaction in _dataAccessInterface.Transactions select transaction.Date).Max();

            _startDate.MinDate = _endDate.MinDate = _startDate.Value;
            _endDate.MaxDate = _startDate.MaxDate = _endDate.Value;
        }

        private void _enableDescription_CheckedChanged(object sender, EventArgs e)
        {
            _description.Enabled = _descriptionLabel.Enabled = _enableDescription.Checked;
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void _enableCategory_CheckedChanged(object sender, EventArgs e)
        {
            _category.Enabled = _categoryLabel.Enabled = _enableCategory.Checked;
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void _enableCategoryGroup_CheckedChanged(object sender, EventArgs e)
        {
            _categoryGroup.Enabled = _categoryGroupLabel.Enabled = _enableCategoryGroup.Checked;
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void _enableAccount_CheckedChanged(object sender, EventArgs e)
        {
            _account.Enabled = _accountLabel.Enabled = _enableAccount.Checked;
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void _enableDate_CheckedChanged(object sender, EventArgs e)
        {
            _startDate.Enabled = _endDate.Enabled = _dateLabel.Enabled = _enableDate.Checked;

            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void _applyButton_Click(object sender, EventArgs e)
        {
            ApplyFilter();
        }

        private void _instantUpdate_CheckedChanged(object sender, EventArgs e)
        {
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void _enableType_CheckedChanged(object sender, EventArgs e)
        {
            _type.Enabled = _typeLabel.Enabled = _enableType.Checked;
            if (_instantUpdate.Checked)
            {
                ApplyFilter();
            }
        }

        private void SearchTransactions_Load(object sender, EventArgs e)
        {
            if (_form == null)
            {
                _form = this;
            }
            else
            {
                _form.Focus();
                this.Close();
            }
        }

        private void SearchTransactions_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (_form == this)
            {
                _form = null;
            }
        }
    }
}
